#pragma once
#include "noncopyable.h"
#include "EventLoop.h"
#include "Sock.h"
#include "InetAddress.h"
#include "callbacks.h"
#include "Buffer.h"

#include <string>
#include <atomic>

class Channel;
class EventLoop;
class Socket;

/*
    TcpConnection 从 Acceptor中拿到对应的connfd
    打包为一个TcpConnecti，通过设置回调设置给相应的channel ，然后底层epoll监听channel进行事件监听
*/
class TcpConnection : noncopyable,public std::enable_shared_from_this<TcpConnection>
{
public:
    TcpConnection(EventLoop *loop, const std::string &name, int sockfd, const InetAddress &localAdd, const InetAddress &peerAddr);

    ~TcpConnection();

    EventLoop *getLoop() { return loop_; }
    const std::string name() const { return name_; } 
    const InetAddress& localAddress() const { return localAddr_; }
    const InetAddress& peerAddress() const { return peerAddr_; }
    bool connected() const { return state_ == KConnected; }
    bool disconnected() const { return state_ == KDisconnected; }

    void send(const std::string & buf);
    void sendInLoop(const void* message,size_t len);

    void shutdown();
    void shutdownInLoop();

    void setConnectionCallback(const ConnectionCallback& cb) { connectionCallback_ = cb; }
    void setMessageCallback(const MessageCallback& cb) { messageCallback_ = cb; }
    void setWriteCompleteCallback(const WriteCompleteCallback& cb) { writeCompleteCallback_ = cb; }
    void setHighWaterMarkCallback(const HighWaterMarkCallback& cb,size_t highWaterMark) { highWaterMarkCallback_ = cb; highWaterMark_ = highWaterMark_; }
    void setCloseCallback(const CloseCallback& cb) { closeCallback_ = cb; }

    void connectEstablished();
    void connectDestroyed();

private:
    enum StateE { KDisconnected, KConnecting, KConnected, KDisconnecting };
    void setState(StateE s) { state_ = s; }
    void handleRead(Timestamp receiveTime);
    void handleWrite();
    void handleClose();
    void handleError();

    EventLoop *loop_;   // 这里不是baseLoop，因为TcpConnectio都是在subLoop中管理的
    const std::string name_;
    std::atomic_int state_;
    bool reading_;
    std::unique_ptr<Socket> socket_;
    std::unique_ptr<Channel> Channel_;
    const InetAddress localAddr_;
    const InetAddress peerAddr_;
    
    ConnectionCallback connectionCallback_;       // 有新连接时候的回调
    MessageCallback messageCallback_;             // 有读写消息时的回调
    WriteCompleteCallback writeCompleteCallback_; // 消息发送完成的回调
    HighWaterMarkCallback highWaterMarkCallback_;
    CloseCallback closeCallback_;

    size_t highWaterMark_;
    Buffer inputBuffer_;
    Buffer outputBuffer_;
};